package com.example.demo.task;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestClient;

import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * url参数执行
 */
@Slf4j
public class TaskRequestExecutor {

    /**
     * 任务执行
     *
     * @param taskInfo taskInfo
     * @param taskExecutor taskExecutor
     */
    public static void exec(TaskInfo taskInfo, TaskExecutor taskExecutor) {
        if (Objects.isNull(taskInfo)) {
            return;
        }
        Map<String, Object> params = taskInfo.getParams();
        if (Objects.nonNull(taskExecutor)) {
            log.info(">>>>>>>>>>>>>>>>>任务执行<<<<<<<<<<<<<<<<<<<");
            taskExecutor.execute(params);
            taskInfo.setNextExecutionTime(calculateNextExecution(taskInfo.getCronExpression()));
            taskInfo.setLastExecutionTime(LocalDateTime.now());
            return;
        }
        String url = taskInfo.getUrl();
        if (Objects.isNull(url) || url.isBlank()) {
            return;
        }
        taskInfo.setNextExecutionTime(calculateNextExecution(taskInfo.getCronExpression()));
        taskInfo.setLastExecutionTime(LocalDateTime.now());
        boolean flag = !CollectionUtils.isEmpty(params);
        if (HttpMethod.GET.matches(taskInfo.getMethod())) {
            if (flag) {
                String paramStr = params.entrySet().stream()
                        .map(x -> x.getKey() + "=" + x.getValue()).collect(Collectors.joining("&"));
                url = url + "?" + paramStr;
            }
            RestClient.create()
                    .get()
                    .uri(url, params)
                    .retrieve().body(String.class);
        } else {
            RestClient.RequestBodySpec requestBodySpec = RestClient.create().post()
                    .uri(url);
            if (flag) {
                requestBodySpec.body(params);
            }
            requestBodySpec.retrieve().body(String.class);
        }
    }


    /**
     * 计算下次执行时间
     * @param cronExpression cronExpression
     */
    public static Instant calculateNextExecution(String cronExpression) {
        CronTrigger trigger = new CronTrigger(cronExpression);
        return trigger.nextExecution(new SimpleTriggerContext());
    }
}